﻿
using HSJM.Service.MWS.Utility.Logs;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;

namespace HSJM.Service.MWS.Utility
{
    /// <summary>
    /// redis简单封装
    /// 朱润来
    /// 2022年8月19日10:33:33
    /// </summary>
    public class RedisHelper
    {
        private static IDatabase cache;
        private static ConnectionMultiplexer connection;
        public RedisHelper()
        {
            cache = StackExchangeConn.GetFactionConn.GetDatabase(8);
            connection = StackExchangeConn.GetFactionConn;
        }

        /// <summary>
        /// 发布redis消息
        /// 朱润来
        /// 2023年3月9日13:55:47
        /// </summary>
        /// <param name="key"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public async Task<bool> PublishMsg(string key, string msg)
        {
            try
            {
                ISubscriber sub = connection.GetSubscriber();
                await sub.PublishAsync(key, msg);
                return true;
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 发布redis消息
        /// 朱润来
        /// 2023年3月9日13:55:47
        /// </summary>
        /// <param name="key"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public async Task<bool> PublishMsg<T>(string key, T msg)// where T :class
        {
            try
            {
                ISubscriber sub = connection.GetSubscriber();
                await sub.PublishAsync(key, JsonConvert.SerializeObject(msg));
                return true;
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 订阅消息
        /// 朱润来
        /// 2023年3月9日13:59:15
        /// </summary>
        /// <param name="key"></param>
        /// <param name="action"></param>
        public async Task SubscribeMsg(string key, Action<RedisChannel, RedisValue> action)
        {
            ISubscriber sub = connection.GetSubscriber();
            await sub.SubscribeAsync(key, action);
        }

        /// <summary>
        /// 添加string类型数据到redis
        /// 朱润来
        /// 2022年8月22日14:40:29
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        public async Task<bool> StringSet(string key, string value)
        {
            try
            {
                return await cache.StringSetAsync(key, value).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }

        }

        /// <summary>
        /// 从redis中获取string类型数据
        /// 朱润来
        /// 2022年8月22日14:40:29
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        public async Task<string> StringGet(string key)
        {
            try
            {
                return await cache.StringGetAsync(key).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return null;
            }

        }

        /// <summary>
        /// 从redis中获取Int类型数据
        /// 朱润来
        /// 2022年8月22日14:40:29
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        public async Task<int> IntGet(string key)
        {
            try
            {
                return Convert.ToInt32(await StringGet(key).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return (-9999);
            }
        }

        /// <summary>
        /// 根据key获取指定类型数据
        /// 朱润来
        /// 2022年8月22日14:40:29
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<T> Get<T>(string key)
        {
            try
            {
                var v = await cache.StringGetAsync(key).ConfigureAwait(false);
                if (v.IsNull)
                {
                    return default(T);
                }
                var list = JsonConvert.DeserializeObject<T>(v);
                return list;
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return default(T);
            }

        }

        /// <summary>
        /// 根据key获取object类型数据
        /// 朱润来
        /// 2022年8月22日14:40:29
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<object> Get(string key)
        {
            try
            {
                var list = await cache.StringGetAsync(key).ConfigureAwait(false);
                return list;
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return null;
            }

        }

        /// <summary>
        /// 将数据添加到redis中
        /// 朱润来
        /// 2022年8月22日14:40:29
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        public async Task<bool> Set(string key, object value)
        {
            try
            {
                return await cache.StringSetAsync(key, JsonConvert.SerializeObject(value)).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }

        }

        /// <summary>
        /// 队列从左边插入
        /// 朱润来
        ///2023年3月13日09:59:35
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<bool> SetListLeft(string key, object value)
        {
            try
            {
                return await cache.ListLeftPushAsync(key, JsonConvert.SerializeObject(value)).ConfigureAwait(false) > 0;
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }

        }

        /// <summary>
        /// 队列从右边插入
        /// 朱润来
        /// 2023年3月13日10:00:03
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public async Task<bool> SetLisRight(string key, object value)
        {
            try
            {
                return await cache.ListRightPushAsync(key, JsonConvert.SerializeObject(value)).ConfigureAwait(false) > 0;
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }

        }

        /// <summary>
        /// 读取队列数据
        /// 朱润来
        /// 2023年3月13日10:08:52
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<List<RedisValue>> ListRange(string key)
        {
            try
            {
                var list = await cache.ListRangeAsync(key).ConfigureAwait(false);
                return list.ToList();
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return null;
            }

        }

        /// <summary>
        /// 队列长度
        /// 朱润来
        /// 2023年3月13日11:36:51
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<long> ListLength(string key)
        {
            try
            {
                var len = await cache.ListLengthAsync(key).ConfigureAwait(false);
                return len;
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return 0;
            }

        }

        /// <summary>
        /// 清除左边
        /// 朱润来
        /// 2023年3月13日10:07:45
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<string> ListLeftPop(string key)
        {
            try
            {
                var list = await cache.ListRightPopAsync(key).ConfigureAwait(false);
                return list.ToString();
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return null;
            }

        }

        /// <summary>
        /// 清除右边
        /// 朱润来
        /// 2023年3月13日10:07:40
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<string> ListRightPop(string key)
        {
            try
            {
                var list = await cache.ListRightPopAsync(key).ConfigureAwait(false);
                return list.ToString();
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return null;
            }

        }

        /// <summary>
        /// 将数据添加到redis中(过期时间)
        /// 朱润来
        /// 2022年8月22日14:40:29
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <param name="expireMinutes">过期时长(分钟)</param>
        /// <returns></returns>
        public async Task<bool> Set(string key, object value, int expireMinutes)
        {
            try
            {
                return await cache.StringSetAsync(key, JsonConvert.SerializeObject(value), TimeSpan.FromMinutes(expireMinutes)).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }

        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <returns></returns>
        public async Task<bool> Remove(string key)
        {
            try
            {
                return await cache.KeyDeleteAsync(key).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }
        }


        #region Hash-CRUD
        /// <summary>
        /// 判断某个数据是否已经被缓存
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dataKey"></param>
        /// <returns></returns>
        public async Task<bool> ExistsHashAsync(string key, string dataKey)
        {
            try
            {
                return await cache.HashExistsAsync(key, dataKey);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 存储数据到hash表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="dataKey"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public async Task<bool> SetHashAsync<T>(string key, string dataKey, T t)
        {
            try
            {
                string json = JsonConvert.SerializeObject(t);
                return await cache.HashSetAsync(key, dataKey, json);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 移除hash中的某值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dataKey"></param>
        /// <returns></returns>
        public async Task<bool> DeleteHashAsync(string key, string dataKey)
        {
            try
            {
                return await cache.HashDeleteAsync(key, dataKey);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 移除hash中的多个值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dataKeys"></param>
        /// <returns></returns>
        public async Task<long> DeleteHashAsync(string key, List<RedisValue> dataKeys)
        {
            try
            {
                return await cache.HashDeleteAsync(key, dataKeys.ToArray());
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return 0;
            }
        }

        /// <summary>
        /// 从hash表获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="dataKey"></param>
        /// <returns></returns>
        public async Task<T> GetHashAsync<T>(string key, string dataKey)
        {
            try
            {
                string value = await cache.HashGetAsync(key, dataKey);
                return JsonConvert.DeserializeObject<T>(value);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return default(T);
            }
        }

        /// <summary>
        /// 为数字增长val
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dataKey"></param>
        /// <param name="val">可以为负</param>
        /// <returns>增长后的值</returns>
        public async Task<double> IncrementHashAsync(string key, string dataKey, double val = 1)
        {
            try
            {
                return await cache.HashIncrementAsync(key, dataKey, val);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return 0;
            }
        }

        /// <summary>
        /// 为数字减少val
        /// </summary>
        /// <param name="key"></param>
        /// <param name="dataKey"></param>
        /// <param name="val">可以为负</param>
        /// <returns>减少后的值</returns>
        public async Task<double> DecrementHashAsync(string key, string dataKey, double val = 1)
        {
            try
            {
                return await cache.HashDecrementAsync(key, dataKey, val);
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return 0;
            }
        }

        /// <summary>
        /// 获取hashkey所有Redis key
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<List<T>> GetHashKeysAsync<T>(string key)
        {
            try
            {
                RedisValue[] values = await cache.HashKeysAsync(key);
                return JsonConvert.DeserializeObject<List<T>>(values.ToString());
            }
            catch (Exception ex)
            {
                MyLogger.Logger.Error(ex.Message);
                return default(List<T>);
            }
        }
        #endregion
    }
}
